/*
 * @Author: liszter <liszter@qq.com>
 * @Date: 2024-02-19 16:18:32
 * @LastEditTime: 2024-02-28 14:28:56
 * @LastEditors: lishutao
 * @Description: 目标：运用数学知识设计特定形状的星系
 * @FilePath: \three学习代码\demo-08\src\main\main.js
 */
import * as THREE from "three";
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(
  75, // 视角
  window.innerWidth / window.innerHeight, // 宽高比
  0.1, // 近平面
  1000 // 远平面
);
camera.position.z = 5;

// 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建几何体
// const geometry = new THREE.BoxGeometry(1, 1, 1);

// // 创建材质
// const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

// // 创建网格
// const cube = new THREE.Mesh(geometry, material);

// // 将网格添加至场景中
// scene.add(cube);



// 添加控制器
  // 添加轨道控制器
  const controls = new OrbitControls(camera, renderer.domElement);
// 设置带阻尼的惯性
controls.enableDamping = true;// 设置阻尼系数
controls.dampingFactor = 0.05;


// 添加辅助线
function addHelpers() {
  const axes = new THREE.AxesHelper(5);
  scene.add(axes);
}

addHelpers()






// 图形对象
const params = {
  count: 100000,  /// 点的数量
  size: 0.01,   // 点的尺寸
  radius: 8,    // 整体的弧形
  branch: 8,    // 分支
  color: "#ff6030",   // 色系
  rotateScale: 0.3,    // 角度
  endColor: "#1b3900",   // 结束处颜色
};


let geometry = null;
let material = null;
let points = null;
const centerColor = new THREE.Color(params.color);
const endColor = new THREE.Color(params.endColor);



const generateGalaxy = () => {

  // 生成定点 
  geometry = new THREE.BufferGeometry()

  // 随机生成位置
  const positions = new Float32Array(params.count * 3)

  // 设置定点颜色
  const colors = new Float32Array(params.count * 3)

  // 循环生成点
  for( let i = 0; i < params.count; i++) {
    
    // 当前的点应该在哪一条分支的角度上 
    const branchAngel = (i % params.branch) * ((2 * Math.PI) / params.branch)

    // 计算当前点距离圆心的距离

    const distance = Math.random() * params.radius * Math.pow(Math.random(), 3);
    const current = i * 3;

    const randomX =
      (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 5;
    const randomY =
      (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 5;
    const randomZ =
      (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 5;


      
      positions[current] =
      Math.cos(branchAngel + distance * params.rotateScale) * distance +
      randomX;
    positions[current + 1] = 0 + randomY;
    positions[current + 2] =
      Math.sin(branchAngel + distance * params.rotateScale) * distance +
      randomZ;


        // 混合颜色，形成渐变色
        const mixColor = centerColor.clone();
        mixColor.lerp(endColor, distance / params.radius);
    
        colors[current] = mixColor.r;
        colors[current + 1] = mixColor.g;
        colors[current + 2] = mixColor.b;

  }


  geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
  geometry.setAttribute("color", new THREE.BufferAttribute(colors, 3));



    //   设置点材质
    material = new THREE.PointsMaterial({
      // color: new THREE.Color(params.color),
      size: params.size,
      sizeAttenuation: true,
      depthWrite: false,
      blending: THREE.AdditiveBlending,
      // map: particlesTexture,
      // alphaMap: particlesTexture,
      transparent: true,
      vertexColors: true,
    });
  
    points = new THREE.Points(geometry, material);
    scene.add(points);


}


generateGalaxy();





























// 渲染循环
function animate() {
  requestAnimationFrame(animate);

  // cube.rotation.x += 0.01;
  // cube.rotation.y += 0.01;
    // 轨道控制器的使用
    controls.update();
  renderer.render(scene, camera);
}

animate();